package cn.xiaolang.thread.threadlocal;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author Dean
 * @date 2021-01-18
 */
@Slf4j
public class ThreadLocalConcurrentIssue {

    private static final Executor poolExecute = Executors.newFixedThreadPool(1);
    private static final ThreadLocal<TargetUser> threadLocal = new ThreadLocal<>();


    public static void main(String[] args) throws InterruptedException {
        threadLocal.set(new TargetUser("dean-parent"));
        poolExecute.execute(new ChildThread("task1"));
        // 1.线程复用，导致线程池内threadLocal的值变动
        poolExecute.execute(new ChildThread("task2"));
        poolExecute.execute(new ChildThread("task3"));
        // 2.父线程获取值不变
        log.info("parent get directly result:{}", threadLocal.get());
        TimeUnit.SECONDS.sleep(3);
        threadLocal.remove();
    }


    static class ChildThread implements Runnable {

        private final String taskName;

        public ChildThread(String taskName) {
            this.taskName = taskName;
        }

        @Override
        public void run() {

            //如果启用了线程（调用start方法），调用get方法是获取不到值的
            TargetUser originVal = threadLocal.get();
            // 修改父线程获取到的值
            threadLocal.set(new TargetUser("modified by[" + taskName + "]"));
            log.info("[{}] get from parent directly:[{}],Now:{}", taskName, originVal,threadLocal.get());


        }
    }

    @Data
    @AllArgsConstructor
    private static class TargetUser {

        private String name;

    }

}

